package com.d2rabbit.exception.aspect;

import cn.hutool.log.StaticLog;
import com.d2rabbit.exception.annotation.CheckException;
import com.d2rabbit.exception.exception.CustomerException;
import com.d2rabbit.exception.exception.DefaultException;
import com.d2rabbit.exception.exception.handler.Validator;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class CheckExceptionAspect {
	/*
	 * 设置切入点
	 * */
	@Pointcut(value = "@annotation(com.d2rabbit.exception.annotation.CheckException)")
	public void exceptionAspect() {

	}

	/*
	 * 方法之前
	 * */
	@Before("exceptionAspect()")
	public void doBeforeCheckException(JoinPoint joinPoint) {
		StaticLog.info("日志输出----------args={}", joinPoint.getClass());
		//class_method
		StaticLog.info("日志输出----------class_method={}", joinPoint.getSignature().getDeclaringTypeName() + "," + joinPoint.getSignature().getName());
		//args[]
		StaticLog.info("日志输出----------args={}", joinPoint.getArgs());
	}

	@After("exceptionAspect()")
	public void doAfterCheckException(JoinPoint joinPoint) {

		StaticLog.info("-----------------异常捕捉操作-----------------------");
	}

	@Around("exceptionAspect()")
	public Object aroundCheckException(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
		Method method = signature.getMethod();
		CheckException checkException = method.getAnnotation(CheckException.class);
		Class<? extends Exception> exceptionClazz = checkException.exception();
		Object result = null;
		int exceptionCode = checkException.code();
		String exceptionMeg = checkException.message();
		try {
			result = proceedingJoinPoint.proceed();
		} catch (Exception e) {
			StaticLog.error("真实错误信息-----------------{}", e);
			if (!(e instanceof CustomerException)) {
//				默认异常抛出
				if (exceptionClazz.equals(DefaultException.class)) {
					Validator.throwDefaultException(exceptionMeg);
				} else {
//					自定义的信息和异常类型抛出
					Class<? extends CustomerException> customerExceptionClazz = exceptionClazz.asSubclass(CustomerException.class);
					throw customerExceptionClazz.getConstructor(Integer.class, String.class).newInstance(exceptionCode, exceptionMeg);
				}
			} else {
				StaticLog.error(e);
			}

		}

		return result;
	}
}
